/*
 * ChatAdmin.cpp
 *
 *  Created on: Dec 2, 2013
 *      Author: gonprieto
 */

#include "Chat_Admin.h"
#include "../communication/Mensajes/MensajeQueryChatsResponse.h"
#include "../utils/Logger.h"
#include <iostream>
#include <fstream>
#include "../utils/Tp2Utils.h"

Chat_Admin::Chat_Admin() :queue(MAIN_QUEUE, 'a'){
}

Chat_Admin::~Chat_Admin() {
}


void Chat_Admin::obtenerListadoChats(unsigned int id){
	std::string listadoChats;
	std::map<unsigned int,std::string>::iterator it = chats.begin();
	for (it= chats.begin(); it != chats.end(); ++it) {
		listadoChats += (*it).second;
	}

	MensajeQueryChatsResponse* response = new MensajeQueryChatsResponse(listadoChats);

	queue.escribirMensaje(id,response);
	delete response;

}


bool Chat_Admin::registrarNuevoCliente(MensajeAgregarUsuario* messageAddUser){

	unsigned int id = messageAddUser->getPid();
	std::string chatName =messageAddUser->getNombreChat();


	if ( chatName.empty()){
		Logger::getInstance().logMessage(Logger::ERROR, "Chat_Admin::registrarNuevoCliente, Error, chat name empty");
	}

	Logger::getInstance().logMessage(Logger::TRACE, "Chat_Admin::registrarNuevoCliente, Size : " + UtilString::intToString(chats.size()));

	bool exito(false);
	if(!chatExiste(chatName)){
		//creo el archivo
		std::ofstream outfile (Tp2Utils::getNombreQueue(chatName).c_str());
		outfile.close();
	}

	std::string nombreChatCliente =  clienteExiste(id);
	if ( nombreChatCliente.empty() || nombreChatCliente.compare(chatName) != 0 ){
		std::stringstream ss;
		ss << "Chat_Admin::registrarNuevoCliente, nombre chat: " << chatName;
		ss << " - id: " << UtilString::intToString(id) << std::endl ;
		Logger::getInstance().logMessage(Logger::TRACE, ss.str());

		//Envio la conexion a los clientes existentes
		enviarMensajeAGrupo(messageAddUser,chatName);

		chats[id] = chatName;
		exito = true;
	}else{
		Logger::getInstance().logMessage(Logger::ERROR, "Chat_Admin::registrarNuevoCliente, ya existe el mismo usuario en :" + nombreChatCliente);
	}

	Logger::getInstance().logMessage(Logger::TRACE, "Salgo de Chat_Admin::registrarNuevoCliente, Size : " + UtilString::intToString(chats.size()));

	return exito;
}
bool Chat_Admin::unregistrarCliente(MensajeRemoverUsuario* messageRemover){

	unsigned int cliente = messageRemover->getPid();
	Logger::getInstance().logMessage(Logger::TRACE, "Entro de Chat_Admin::unregistrarCliente, Size : " + UtilString::intToString(chats.size()));

	std::map<unsigned int,std::string >::iterator it = chats.begin();

	for (it= chats.begin(); it != chats.end(); ++it) {
		if ( (*it).first == cliente){

			chats.erase(it);

			enviarMensajeAGrupo(messageRemover,(*it).second);

			Logger::getInstance().logMessage(Logger::TRACE, "Salgo de Chat_Admin::unregistrarCliente, Size : " + UtilString::intToString(chats.size()));
			return true;
		}
	}

	return false;
}

bool Chat_Admin::chatExiste(std::string chatName){
	//Recorro la lista de usuarios y busco el nombre
	std::map<unsigned int,std::string>::iterator it = chats.begin();

	for (it= chats.begin(); it != chats.end(); ++it) {
		if ( (*it).second.compare(chatName) == 0){
			//Encontre el nombre salgo

			Logger::getInstance().logMessage(Logger::TRACE, "Encontre el chat:"+ (*it).second );
			return true;
		}
 	}

	return false;
}

std::string Chat_Admin::clienteExiste(unsigned int id){
	//Recorro la lista de usuarios y busco el nombre
	std::map<unsigned int,std::string>::iterator it = chats.begin();

	for (it= chats.begin(); it != chats.end(); ++it) {
		if ( (*it).first == id){

			Logger::getInstance().logMessage(Logger::TRACE, "Cliente encontrado en chat:"+ (*it).second + " - Id:" + UtilString::intToString(id));

			//Encontre el nombre salgo
			return (*it).second;
		}
 	}

	return "";
}

void Chat_Admin::enviarMensajeAGrupo(MensajeConAutorYPid* msg,std::string chat){

	if( chat.empty() ){
		Logger::getInstance().logMessage(Logger::ERROR, "No se pudo encontrar el chat para el cliente . id:" + UtilString::intToString(msg->getPid()));
		return;
	}

	mensajeAChat(chat,msg->getPid(),msg);
}

void Chat_Admin::enviarMensaje(MensajeConAutorYPid* msg){
	//Obtengo el chat al que pertenece el usuario
	std::string chatCliente = clienteExiste(msg->getPid());

	if( chatCliente.empty() ){
		Logger::getInstance().logMessage(Logger::ERROR, "No se pudo encontrar el chat para el cliente . id:" + UtilString::intToString(msg->getPid()));
		return;
	}

	mensajeAChat(chatCliente,msg->getPid(),msg);
}

void Chat_Admin::mensajeAChat(std::string nombreChat,unsigned int omitir,MensajeConAutorYPid* msg){
	//Recorro la lista de usuarios y busco el nombre
	std::map<unsigned int,std::string>::iterator it = chats.begin();

	for (it= chats.begin(); it != chats.end(); ++it) {
		if ( (*it).second.compare(nombreChat)== 0){
			if ( (*it).first != omitir ){
				Logger::getInstance().logMessage(Logger::TRACE, "Envio mensaje a user id:" + UtilString::intToString((*it).first));
				queue.escribirMensaje((*it).first,msg);
			}
		}
	}
}

